<?php

namespace common\models;

use Yii;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
use common\library\traits\APITrait;
use common\commands\VtCommon;
use api\modules\v1\models\MemberData;
use api\modules\v1\models\MemberRecommend;

/**
 * Member model
 *
 * @property integer $id
 * @property string $username
 * @property string $password_hash
 * @property string $password_reset_token
 * @property string $email
 * @property integer $status
 * @property integer $created_time
 * @property integer $updated_time
 * @property string $password write-only password
 */
class Member extends ActiveRecord implements IdentityInterface
{
    const STATUS_DELETED = 0;
    const STATUS_ACTIVE = 1;

    use APITrait;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%member}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            ['status', 'default', 'value' => self::STATUS_ACTIVE],
            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]]
        ];
    }

    /**
     * [fields 返回字段限制]
     * @Author   panwc
     * @DateTime 2017-09-06T16:40:50+0800
     * @return   [array]                   [修改后后的对象数组]
     */
    public function fields()
    {
        $fields = parent::fields();

        // 删除一些包含敏感信息的字段
        unset($fields['password_hash'], $fields['password_reset_token'], $fields['api_token_expire'], $fields['api_token'], $fields['password']);

        return $fields;
    }

    public function extraFields()
    {
        return ['memberData'];
    }

    /**
     * @inheritdoc
     */
    public static function findIdentity($id)
    {
        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
    }

    public static function response($data)
    {
        header('Content-Type: application/json; charset=' . Yii::$app->charset);
        exit(json_encode($data));
    }

    /**
     * [findIdentityByAccessToken token验证]
     * @param    [string]                   $token [token密匙]
     * @param    [string]                   $type  [类型]
     * @return   [obj]                          [用户对象]
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        if (!static::apiTokenIsValid($token)) {
            return static::response(VtCommon::getPackedResponse(TOKEN_FAILED, Yii::t('app', 'TOKEN_FAILED'), null));
        }

        return static::findOne(['api_token' => $token, 'status' => self::STATUS_ACTIVE]);
    }

    /**
     * Finds user by username
     *
     * @param string $username
     * @return static|null
     */
    public static function findByUsername($username)
    {
        $memberType = static::checkUserType($username);

        if ($memberType == 1) {
            $memberData = MemberData::findOne(['email' => $username]);
            return static::findOne(['id' => $memberData->id, 'status' => self::STATUS_ACTIVE]);
        } elseif ($memberType == 2) {
            return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
        }
    }

    public static function checkUserType($username)
    {
        if (filter_var($username, FILTER_VALIDATE_EMAIL)) {
            return 1;
        } else {
            return 2;
        }
    }

    /**
     * @inheritdoc
     */
    public function getId()
    {
        return $this->getPrimaryKey();
    }

    /**
     * @inheritdoc
     */
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    /**
     * @inheritdoc
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }

    /**
     * Validates password
     *
     * @param string $password password to validate
     * @return bool if password provided is valid for current user
     */
    public function validatePassword($password)
    {
        return Yii::$app->security->validatePassword($password, $this->password_hash);
    }

    /**
     * Generates password hash from password and sets it to the model
     *
     * @param string $password
     */
    public function setPassword($password)
    {
        $this->password_hash = Yii::$app->security->generatePasswordHash($password);
    }

    /**
     * [generateApiToken 生成apiToken]
     * @Author   panwc
     * @DateTime 2017-09-05T14:50:11+0800
     */
    public function generateApiToken()
    {
        $this->api_token = Yii::$app->security->generateRandomString() . '_' . time();//获取token
        $expire = Yii::$app->params['user.apiTokenExpire'];
        $this->api_token_expire = time() + $expire;//设置token过期时间
        $this->update_time = time();//登录时间
        $this->last_ip = Yii::$app->request->getUserIP();
    }

    /**
     * [generateRecommendCode 生成邀请码]
     */
    public function generateRecommendCode()
    {
        $memberRecommend = new MemberRecommend();

        $recommend_code = substr(md5(uniqid(mt_rand(1000, 9999), true)), 26);

        $memberRecommendCodeResult = $memberRecommend::find()->from('{{%member_recommend}}')->select('id')
            ->where(['recommend_code' => $recommend_code])
            ->asArray()
            ->one();

        if (!empty($memberRecommendCodeResult)) return static::generateRecommendCode();

        $memberRecommend->recommend_code = $recommend_code;
        $memberRecommend->create_time = time();

        if (!$memberRecommend->validate()) {
            $this->response(VtCommon::getPackedResponse(DATABASE_FAILED, Yii::t('app', 'DATABASE_FAILED'), null));
        }

        $tr = Yii::$app->db->beginTransaction();
        try {

            if (!$memberRecommend->save()) {
                throw new \Exception('DATABASE_FAILED');
            }

            $tr->commit();

        } catch (\Exception $e) {
            $this->response(VtCommon::getPackedResponse(DATABASE_FAILED, Yii::t('app', 'DATABASE_FAILED'), null));
        }

        return $memberRecommend->id;
    }

    /**
     * [getParentId 获取推荐人id]
     * @param $recommend_code
     * @param bool $status 是否定义推荐码
     */
    public function getParentId($recommend_code, $status = true)
    {
        $memberRecommendCodeResult = [];

        if ($status) {
            $memberRecommend = new MemberRecommend();

            $memberRecommendCodeResult = $memberRecommend::find()->from('{{%member_recommend}}')->select('id')
                ->where(['recommend_code' => $recommend_code])
                ->asArray()
                ->one();
        }

        return !empty($memberRecommendCodeResult) ? $memberRecommendCodeResult['id'] : static::response(VtCommon::getPackedResponse(DATABASE_FAILED, Yii::t('app', '{attribute} does not exist!', ['attribute' => Yii::t('app', 'recommend_code')]), null));
    }

    /**
     * [apiTokenIsValid 检验apiToken是否有效]
     * @Author   panwc
     * @DateTime 2017-09-05T14:33:27+0800
     * @param    [string]                   $token [token密匙]
     * @return   [Boolean]                          [是否有效]
     */
    public static function apiTokenIsValid($token)
    {
        if (empty($token)) {//如果token为空
            return false;
        }
        $user = static::findOne(['api_token' => $token, 'status' => self::STATUS_ACTIVE]);//获取当前登录人信息
        if (empty($user)) {
            return false;
        }
        $apiTokenExpire = $user->api_token_expire;//将过期时间时间戳化
        // $timeStamp = (int) substr($token, strrpos($token, '_') + 1);
        $expire = Yii::$app->params['user.apiTokenExpire'];

        if ($apiTokenExpire < time()) {//判断是否过期，如果过期时间戳小于当前时间戳  则为已经过期   如果过期时间戳大于当前时间戳则代表token还有效
            return false;
        } else {
            $newApiTokenExpire = time() + $expire;//新的过期时间
            $user->api_token_expire = $newApiTokenExpire;
            $user->last_ip = Yii::$app->request->getUserIP();
            $user->save();

            return true;
        }

    }
}
